<?php
/**
 * 一个api的例子
 *
 * friends.get
 * 
 * 将请求参数格式化为“key=value”格式，即“k1=v1”、“k2=v2”、“k3=v3”；
 * 将上诉格式化好的参数键值对，以字典序升序排列后，拼接在一起，即“k1=v1k2=v2k3=v3”；
 * 在上拼接好的字符串末尾追加上应用的Secret Key；
 * 上述字符串的MD5值即为签名的值。
 *
 * 注意：计算sig时的字符串，必须用UTF-8编码。
 * 注意：计算sig的时候不需要对参数进行URLEncode（“application/x-www-form-urlencoded”编码），但是发送请求的时候需要进行URLEncode。
 * 注意：有很多开发者在计算签名的时候，将参数名和参数值误使用“application/x-www-form-urlencoded”编码，导致签名验证失败。
 */
@header('Pragma:no-cache');
@header('Cache-Control:no-cache');
$session_key = $_GET['session_key'];

$url = 'http://api.renren.com/restserver.do';

/*$params = array(
	'api_key' => '9bbac42e58c844cd85c89aa7529c6f00', //oauth_consumer_key
	'method' => 'friends.get',
	'call_id' => array_pop(explode(' ', microtime())), //当前调用请求队列号，建议使用当前系统时间的毫秒值。
	'v' => '1.0',
	'session_key' => $session_key,
	'format' => 'json',
	'page' => '1',
	'count' => '500',
);*/
$params = array(
	'api_key' => '9bbac42e58c844cd85c89aa7529c6f00',
	'call_id' => array_pop(explode(' ', microtime())), //当前调用请求队列号，建议使用当前系统时间的毫秒值。
	'count' => 500,
	'format' => 'json',
	'method' => 'friends.get',
	'page' => 1,
	'session_key' => $session_key,
	'v' => '1.0',
);
ksort($params);

$params['sig'] = getSig($params);
print_r($params);

$ret = http($url, 'POST', $params);
echo $ret;

//
function getSig($params) {
	$oauth_consumer_token_secret = '7e099f5ebb8346c18453fd2539f47555';
	array_walk($params, 'concatParams');
	$params = array_values($params);
	sort($params);
	$sig = implode('', $params);
	$sig .= $oauth_consumer_token_secret;
	return md5($sig);
}

function concatParams(&$val, $key) {
	$val = "{$key}={$val}";
}

function http($url, $method, $postfields = array(), $multi = false){
	$urlArr = parse_url($url);
	//check https
	$version = '1.1';
	$host = $header_host = isset($urlArr['host']) ? $urlArr['host'] : '';
	if('https' === strtolower($urlArr['scheme'])) {
		$port = (isset($urlArr['port']) && '443' !== $urlArr['port']) ? $urlArr['port'] : '443';
		$host = "tls://{$host}";
	} else {
		$port = (isset($urlArr['port']) && '80' !== $urlArr['port']) ? $urlArr['port'] : '80';
	}
	
	$requestPath = $urlArr['path'];
	if(isset($urlArr['query'])) $requestPath .= "?{$urlArr['query']}";

	$header = "{$method} {$requestPath} HTTP/{$version}\r\n";
	$header .= "Host: {$header_host}\r\n";
	if('post' === strtolower($method)) {
		//handle $postfields
		$postfieldsStr = '';
		if($multi) {
			$boundary = "---------------------------".substr(md5(rand(0,32000)),0,10);
			$header .= "Content-Type: multipart/form-data; boundary={$boundary}\r\n";
			foreach($postfields as $key => $val) {
				$postfieldsStr .= "--{$boundary}\r\n";
				if(is_file($val) && file_exists($val)) {
					$postfieldsStr .= "Content-Disposition: form-data; name=\"{$key}\"; filename=\"" . basename($val) . "\"\r\n";
					$postfieldsStr .= "Content-Type: " . getMimeType($val) . "\r\n\r\n";
					$postfieldsStr .= file_get_contents($val) . "\r\n";
				} else {
					$postfieldsStr .= "Content-Disposition: form-data; name=\"{$key}\"\r\n\r\n";
					$postfieldsStr .= "{$val}\r\n";
				}
			}
			
			$postfieldsStr .= "--{$boundary}--\r\n";
		} else {
			$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
			foreach($postfields as $key => $val) {
				$postfieldsStr .= urlencode($key) . '=' . urlencode($val) . '&';
			}
			$postfieldsStr = substr($postfieldsStr, 0, -1);
		}
		
		$header .= "Content-Length: ".strlen($postfieldsStr)."\r\n";
		$header .= "Connection: Close\r\n\r\n";
		$header .= $postfieldsStr;
	} else {
		$header .= "Connection: Close\r\n\r\n";
	}

	$ret = '';
	
	$fp = @fsockopen($host,$port,$errno,$errstr,30);

	if(!$fp) {
		throw new Exception('open socket fail');
	} else {
		fwrite($fp, $header);
		while(!feof($fp)) {
			$ret .= fgets($fp, 4096);
		}
		fclose($fp);
		if(false !== strrpos($ret,'Transfer-Encoding: chunked')){
			$info = explode("\r\n\r\n",$ret);
			$response = explode("\r\n",$info[1]);
			$t = array_slice($response,1,-1);

			$returnInfo = implode('',$t);
		}else{
			$response = explode("\r\n\r\n",$ret);
			$returnInfo = $response[1];
		}
		
		return $returnInfo;
	}
}

function getMimeType($filename) {
	$mime_types = array(
		'txt' => 'text/plain',
		'htm' => 'text/html',
		'html' => 'text/html',
		'php' => 'text/html',
		'css' => 'text/css',
		'js' => 'application/javascript',
		'json' => 'application/json',
		'xml' => 'application/xml',
		'swf' => 'application/x-shockwave-flash',
		'flv' => 'video/x-flv',
		
		// images
		'png' => 'image/png',
		'jpe' => 'image/jpeg',
		'jpeg' => 'image/jpeg',
		'jpg' => 'image/jpeg',
		'gif' => 'image/gif',
		'bmp' => 'image/bmp',
		'ico' => 'image/vnd.microsoft.icon',
		'tiff' => 'image/tiff',
		'tif' => 'image/tiff',
		'svg' => 'image/svg+xml',
		'svgz' => 'image/svg+xml',
		
		// archives
		'zip' => 'application/zip',
		'rar' => 'application/x-rar-compressed',
		'exe' => 'application/x-msdownload',
		'msi' => 'application/x-msdownload',
		'cab' => 'application/vnd.ms-cab-compressed',
		
		// audio/video
		'mp3' => 'audio/mpeg',
		'qt' => 'video/quicktime',
		'mov' => 'video/quicktime',
		
		// adobe
		'pdf' => 'application/pdf',
		'psd' => 'image/vnd.adobe.photoshop',
		'ai' => 'application/postscript',
		'eps' => 'application/postscript',
		'ps' => 'application/postscript',
		
		// ms office
		'doc' => 'application/msword',
		'rtf' => 'application/rtf',
		'xls' => 'application/vnd.ms-excel',
		'ppt' => 'application/vnd.ms-powerpoint',
		
		// open office
		'odt' => 'application/vnd.oasis.opendocument.text',
		'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
	);
	
	$ext = strtolower(array_pop(explode('.',$filename)));
	if (array_key_exists($ext, $mime_types)) {
		return $mime_types[$ext];
	} elseif (function_exists('finfo_open')) {
		$finfo = finfo_open(FILEINFO_MIME);
		$mimetype = finfo_file($finfo, $filename);
		finfo_close($finfo);
		return $mimetype;
	} else {
		return 'application/octet-stream';
	}
}

/*function http($url, $method, $postfields = array() , $multi = false){
	$ci = curl_init();
	curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE);
	curl_setopt($ci, CURLOPT_HEADERFUNCTION, 'getHeader');
	curl_setopt($ci, CURLOPT_HEADER, FALSE);

	switch ($method) {
	case 'POST':
		curl_setopt($ci, CURLOPT_POST, TRUE);
		if (!empty($postfields)) {
			curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
		}
		break;
	case 'DELETE':
		curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE');
		if (!empty($postfields)) {
			$url = "{$url}?{$postfields}";
		}
	}

	$header_array = array();
	$header_array2=array();
	if( $multi )
		$header_array2 = array("Content-Type: multipart/form-data; boundary=" . OAuthUtil::$boundary , "Expect: ");
	foreach($header_array as $k => $v)
		array_push($header_array2,$k.': '.$v);

	curl_setopt($ci, CURLOPT_HTTPHEADER, $header_array2 );
	curl_setopt($ci, CURLINFO_HEADER_OUT, TRUE );
	curl_setopt($ci, CURLOPT_URL, $url);

	$response = curl_exec($ci);
	curl_close($ci);
	return $response;
}

function getHeader($ch, $header) {
	$i = strpos($header, ':');
	if (!empty($i)) {
		$key = str_replace('-', '_', strtolower(substr($header, 0, $i)));
		$value = trim(substr($header, $i + 2));
	}
	return strlen($header);
}*/
?>